﻿//**************************
//开发人员：Morning Sun QQ:576830428  微信:MorningSun0125
//业务范围：网站开发、小程序开发、web应用开发,桌面程序开发,工控类软件开发等
//开发日期：2016年1月10日
//版本号：Version 3.0 CopyRight 2011-2029
//**************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;


namespace FileServer
{
    public partial class FormServer : Form
    {
        #region 变量
        /// <summary>
        /// 拖动位置
        /// </summary>
        private Point MousePoint;
        /// <summary>
        /// 是否为鼠标左键
        /// </summary>
        private bool LeftFlag;

        /// <summary>
        /// 监听Socket
        /// </summary>
        Socket ListenSocket;
        /// <summary>
        /// socket配置信息
        /// </summary>
        SocketConfig socketconfig;
        /// <summary>
        /// 监听线程
        /// </summary>
        Thread ListenThread;
        /// <summary>
        /// 发送数据包大小
        /// </summary>
        int SendPacketSize = 1024 * 1024;
        /// <summary>
        /// 接收数据包大小
        /// </summary>
        int ReceivePacketSize = 1024*1024;
        /// <summary>
        /// 发送周期默认500毫秒，1000毫秒等于1s
        /// </summary>
        int SendInterval = 500;
        /// <summary>
        /// 链接的客户端字典
        /// </summary>
        Dictionary<string, Socket> ConnectClientDic = new Dictionary<string, Socket>();
        /// <summary>
        /// 接收客户端消息线程字典
        /// </summary>
        Dictionary<string, Thread> ReceiveDataDic = new Dictionary<string, Thread>();
        /// <summary>
        /// 最后一次修改的文件
        /// </summary>
        string LastChanageFile = "";
        /// <summary>
        /// 命令集合
        /// </summary>
        List<string> ListCMD = new List<string>();
        /// <summary>
        /// 发送命令线程
        /// </summary>
        Thread ThreadSend;
        /// <summary>
        /// 文件监视器字典
        /// </summary>
        Dictionary<string, FileSystemWatcher> WatchDic = new Dictionary<string, FileSystemWatcher>();
        /// <summary>
        /// 文件监控线程
        /// </summary>
        Dictionary<string, Thread> WatchThreadDic = new Dictionary<string, Thread>();
        /// <summary>
        /// 接收服务器信息
        /// </summary>
        DalTbClient dalclient = new DalTbClient();
        /// <summary>
        /// 发布服务器信息
        /// </summary>
        DalTbServer dalserver = new DalTbServer();
        /// <summary>
        /// 接收服务器信息
        /// </summary>
        Dictionary<string, string> ClientDic = new Dictionary<string, string>();
        /// <summary>
        /// 客户端是否占线
        /// </summary>
        Dictionary<string, DateTime> ClientBusyDic = new Dictionary<string, DateTime>();
        #endregion


        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public FormServer()
        {
            InitializeComponent();
            this.FormBorderStyle = FormBorderStyle.None;

            #region 工具栏
            WinIcon.Parent = WinTitlePic;
            labWinTitle.Parent = WinTitlePic;
            labWinMin.Parent = WinTitlePic;
            labWinClose.Parent = WinTitlePic;
            labWinMin.BackgroundImage = global::FileServer.Properties.Resources.winMin;
            labWinClose.BackgroundImage = global::FileServer.Properties.Resources.winClose;
            #endregion

            #region 工作区
            gbLog.Parent = WorkPic;
            gbDir.Parent = WorkPic;
            PTool.Parent = WorkPic;
            #endregion

            #region Tip
            Tips.SetToolTip(ImgSetServer, "发布服务器设置");
            Tips.SetToolTip(ImgClient, "接收服务器管理");
            Tips.SetToolTip(ImgStart, "开启服务");
            Tips.SetToolTip(ImgStop, "停止服务");
            Tips.SetToolTip(ImgClear, "清空日志");
            Tips.SetToolTip(ImgSync, "手动同步");
            Tips.SetToolTip(ImgRefrash, "刷新同步目录");
            Tips.SetToolTip(ImgStatus, "当前状态");
            #endregion            
        }
        #endregion


        #region 加载窗口
        /// <summary>
        /// 加载窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormServer_Load(object sender, EventArgs e)
        {
            MsgBox.AppendText("定制联系微信:MorningSun0125");
        }
        #endregion


        #region   最小化窗体
        /// <summary>
        /// 最小化窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnMin_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }
        #endregion


        #region 关闭窗体
        /// <summary>
        /// 关闭窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnClose_Click(object sender, EventArgs e)
        {

            try
            {
                //关闭发送线程
                ThreadSend.Abort();
                //关闭客户端连接
                foreach (var client in ConnectClientDic)
                {
                    client.Value.Close();
                }
                //终止消息接收线程
                foreach (var client in ReceiveDataDic)
                {
                    client.Value.Abort();
                }
                //关闭socket
                ListenSocket.Close();
                ListenSocket.Dispose();
                //关闭文件夹监控
                foreach (var wc in WatchDic)
                {
                    FileSystemWatcher watcher = wc.Value;
                    watcher.Changed -= new FileSystemEventHandler(OnChanged);
                    watcher.Created -= new FileSystemEventHandler(OnCreated);
                    watcher.Deleted -= new FileSystemEventHandler(OnDeleted);
                    watcher.Renamed -= new RenamedEventHandler(OnReNamed);

                    watcher.EnableRaisingEvents = false;
                }
                //关闭文件夹监控线程
                foreach (var wt in WatchThreadDic)
                {
                    wt.Value.Abort();
                }
                AddMsg("Server:stop server!");
            }
            catch (Exception ex)
            {

            }
            ImgStatus.Image = global::FileServer.Properties.Resources.gray;
            Environment.Exit(0);
            this.Close();
        }
        #endregion


        #region  最小化按钮效果
        /// <summary>
        /// 鼠标悬浮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labWinMin_MouseHover(object sender, EventArgs e)
        {
            labWinMin.BackgroundImage = global::FileServer.Properties.Resources.winMinPressed;
        }


        /// <summary>
        /// 鼠标离开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labWinMin_MouseLeave(object sender, EventArgs e)
        {
            labWinMin.BackgroundImage = global::FileServer.Properties.Resources.winMin;
        }
        #endregion


        #region  关闭按钮效果
        /// <summary>
        /// 关闭按钮悬浮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labWinClose_MouseHover(object sender, EventArgs e)
        {
            labWinClose.BackgroundImage = global::FileServer.Properties.Resources.winClosePressed;
        }


        /// <summary>
        /// 关闭按钮鼠标经过
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labWinClose_MouseLeave(object sender, EventArgs e)
        {
            labWinClose.BackgroundImage = global::FileServer.Properties.Resources.winClose;
        }
        #endregion


        #region 窗体拖动
        private void WinTitlePic_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                MousePoint = new Point(-e.X, -e.Y); //得到变量的值
                LeftFlag = true;                  //点击左键按下时标注为true;
            }
        }

        private void WinTitlePic_MouseMove(object sender, MouseEventArgs e)
        {
            if (LeftFlag)
            {
                Point mouseSet = Control.MousePosition;
                mouseSet.Offset(MousePoint.X, MousePoint.Y);  //设置移动后的位置
                Location = mouseSet;
            }
        }

        private void WinTitlePic_MouseUp(object sender, MouseEventArgs e)
        {
            if (LeftFlag)
            {
                LeftFlag = false;//释放鼠标后标注为false;
            }
        }
        #endregion




        #region 监听客户端
        /// <summary>
        /// 监听客户端
        /// </summary>
        private void AcceptClient()
        {
            try
             {
                 while (true)
                 {
                     //建立一个与客户端通信的套接字 
                     Socket TempSocket = ListenSocket.Accept();
                     IPEndPoint ClientIP = (IPEndPoint)TempSocket.RemoteEndPoint;

                     if (!ConnectClientDic.ContainsKey(ClientIP.Address.ToString()))
                     {
                         ConnectClientDic.Add(ClientIP.Address.ToString(), TempSocket);
                     }
                     else
                     {
                         ConnectClientDic[ClientIP.Address.ToString()] = TempSocket;//保证一个ip仅有一个连接
                     }
                     AddMsg(string.Format("Connect:{0} Connected", ClientIP.Address));

                     //启用一个线程接收数据
                     Thread threadreceive = new Thread(delegate() { ReceiveData(TempSocket); });
                     threadreceive.Start();
                     if (!ReceiveDataDic.ContainsKey(ClientIP.ToString()))
                     {
                         ReceiveDataDic.Add(ClientIP.ToString(), threadreceive);
                     }
                 }
             }
             catch (Exception err)
             {
                 //throw new Exception("");
             }
        }
        #endregion


        #region 接收数据
        /// <summary>
        /// 接收数据
        /// </summary>
        private void ReceiveData(Socket ClientSocket)
        {
            if (ClientSocket != null)
            {
                try
                {
                    IPEndPoint ClientIP = (IPEndPoint)ClientSocket.RemoteEndPoint;
                    //缓冲区
                    byte[] bytes = new byte[ReceivePacketSize];

                    while (true)
                    {
                        //接收数据
                        int butter = ClientSocket.Receive(bytes, 0, ReceivePacketSize, SocketFlags.None);
                        try
                        {
                            if (butter > 0)
                            {
                                #region 命令解析
                                string CMD = System.Text.Encoding.UTF8.GetString(bytes, 0, butter).TrimEnd('\0');
                                AddMsg(CMD);
                                if (CMD.Substring(0, 4) == "Over")
                                {
                                    ClientBusyDic.Remove(ClientIP.Address.ToString().Trim());
                                }
                                #endregion
                            }
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                }
                catch (Exception ex)
                {
                    try
                    {
                        ClientSocket.Close();
                    }
                    catch (Exception exc)
                    {
                    }
                }
            }
        }
        #endregion


        #region 监控文件夹
        /// <summary>
        /// 监控文件夹
        /// </summary>
        /// <param name="wc"></param>
        private void StartWatch(WatchConfig wc)
        {
            if (!WatchDic.ContainsKey(wc.WatchDir))
            {
                FileSystemWatcher watcher = new FileSystemWatcher();
                watcher.Path = wc.WatchDir;//监控目录
                watcher.IncludeSubdirectories = wc.ChildDir;//是否监控子目录
                watcher.Filter = wc.WatchFilter;//监控文件的后缀
                watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;


                watcher.Changed += new FileSystemEventHandler(OnChanged);
                watcher.Created += new FileSystemEventHandler(OnCreated);
                watcher.Deleted += new FileSystemEventHandler(OnDeleted);
                watcher.Renamed += new RenamedEventHandler(OnReNamed);

                watcher.EnableRaisingEvents = true;

                WatchDic.Add(wc.WatchDir,watcher);
            }
        }
        #endregion


        #region 发送任务
        /// <summary>
        /// 发送任务
        /// </summary>
        private void SendData()
        {
            while (true)
            {
                if (ListCMD != null && ListCMD.Count > 0)
                {
                    string ClientIP = ListCMD[0].Split(';')[0];//服务器IP
                    string CMD = ListCMD[0].Split(';')[1];

                    try
                    {
                        //如果客户端连接存在、连接正常并且没被占用则可以发送
                        if (ConnectClientDic.ContainsKey(ClientIP) && ConnectClientDic[ClientIP].Connected && !ClientBusyDic.ContainsKey(ClientIP))
                        {
                            AddMsg("Send:" + CMD);

                            #region 执行命令
                            //记录该客户端被占用
                            ClientBusyDic.Add(ClientIP, DateTime.Now);

                            if (CMD.Substring(0, 8) == "SyncFile")
                            {
                                //同步文件
                                string[] CMDArr = CMD.Split(',');
                                //未被排出
                                if (!CheckExclude(CMDArr[1].ToString().ToLower()))
                                {
                                    //停止一秒检测文件
                                    System.Threading.Thread.Sleep(SendInterval*2);

                                    if (File.Exists(CMDArr[1].ToLower()))
                                    {
                                        FileInfo fileinfo = new FileInfo(CMDArr[1].ToLower());
                                        if (fileinfo.Length > 0)
                                        {
                                            SyncFile(ClientIP, CMDArr[1].ToLower());
                                        }
                                        else
                                        {
                                            //创建文件
                                            SendData(ClientIP, "NewFile," + CMDArr[1].ToLower());
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //发送命令
                                string[] CMDArr = CMD.Split(',');
                                //未被排出
                                if (!CheckExclude(CMDArr[1].ToString().ToLower()))
                                {
                                    SendData(ClientIP, CMDArr[0] + "," + CMDArr[1].ToLower());
                                }
                            }

                            //删除命令
                            ListCMD.Remove(ListCMD[0]);
                            #endregion
                        }
                    }
                    catch (Exception ex)
                    { 
                    
                    }

                    //停止半秒下一条命令
                    System.Threading.Thread.Sleep(SendInterval);
                }
            }
        }
        #endregion    


        #region 文件创建
        /// <summary>
        /// 文件创建
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnCreated(object sender, FileSystemEventArgs e)
        {
            try
            {
                //创建文件夹
                if (FileHelp.CheckFileDir(e.FullPath.ToString()) == 0)
                {
                    foreach (var kv in ClientDic)
                    {
                        if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                        {
                            AddCMD(kv.Key.Trim()+";NewDir," + e.FullPath.ToString());
                        }
                    }

                    #region 创建子目录同步文件
                    //如果有子目录表示移动产生的新建
                    //则创建子目录同步所有文件
                    List<string> list = new List<string>();
                    list = FileHelp.GetAllFolder(e.FullPath.ToString(), list);
                    if (list != null && list.Count > 0)
                    {
                        foreach (string path in list)
                        {
                            //同步文件夹
                            foreach (var kv in ClientDic)
                            {
                                if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                {
                                    AddCMD(kv.Key.Trim()+";NewDir," + path.ToString());
                                }
                            }

                            //同步文件
                            List<string> listfile = FileHelp.GetAllFile(path.ToString());
                            if (listfile != null && listfile.Count > 0)
                            {
                                foreach (string filepath in listfile)
                                {
                                    foreach (var kv in ClientDic)
                                    {
                                        if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                        {
                                            AddCMD(kv.Key.Trim() + ";SyncFile," + filepath);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //同步一级目录文件
                    list = new List<string>();
                    list = FileHelp.GetAllFile(e.FullPath.ToString());
                    if (list != null && list.Count > 0)
                    {
                        foreach (string filepath in list)
                        {
                            foreach (var kv in ClientDic)
                            {
                                if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                {
                                    AddCMD(kv.Key.Trim()+";SyncFile," + filepath);
                                }
                            }
                        }
                    }
                    #endregion
                }

                //创建文件
                if (FileHelp.CheckFileDir(e.FullPath.ToString()) == 1)
                {
                    foreach (var kv in ClientDic)
                    {
                        if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                        {
                            AddCMD(kv.Key.Trim()+";SyncFile," + e.FullPath.ToString());
                        }
                    }
                }
               
            }
            catch (Exception ex)
            { 
            
            }
        }
        #endregion


        #region 文件删除
        /// <summary>
        /// 文件删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnDeleted(object sender, FileSystemEventArgs e)
        {
            foreach (var kv in ClientDic)
            {
                if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                {
                    AddCMD(kv.Key.Trim()+";Del," + e.FullPath.ToString());
                }
            }
        }
        #endregion


        #region 文件重命名
        /// <summary>
        /// 文件重命名
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnReNamed(object sender, RenamedEventArgs e)
        {
            foreach (var kv in ClientDic)
            {
                if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                {
                    AddCMD(kv.Key.Trim()+";Rename," + e.OldFullPath.ToString() + "\r" + e.FullPath.ToString());
                }
            }
        }
        #endregion


        #region 文件改变
        /// <summary>
        /// 文件改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnChanged(object sender, FileSystemEventArgs e)
        {
            //只是文件更改才做操作做
            if (FileHelp.CheckFileDir(e.FullPath.ToString()) == 1)
            {
                FileInfo fi = new FileInfo(e.FullPath.ToString());
                DateTime LastTime = fi.LastWriteTime;
                if (LastChanageFile != (e.FullPath.ToString() + ";" + LastTime.ToString()).ToString().ToLower())
                {
                    LastChanageFile = (e.FullPath.ToString() + ";" + LastTime.ToString()).ToString().ToLower();

                    foreach (var kv in ClientDic)
                    {
                        if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                        {
                            AddCMD(kv.Key.Trim()+";SyncFile," + e.FullPath.ToString());
                        }
                    }
                }
            }                
        }
        #endregion



        #region 命令集合
        /// <summary>
        /// 命令集合
        /// </summary>
        /// <param name="CMD"></param>
        private void AddCMD(string CMD)
        {
            if (!ListCMD.Contains(CMD))
            {
                ListCMD.Add(CMD);
            }
        }
        #endregion


        #region 发送信息
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="cmdstr"></param>
        private void SendData(string ClientIP, string cmdstr)
        {
            
                //处理命令
                cmdstr = cmdstr.Replace(socketconfig.SyncDir.ToLower(), ClientDic[ClientIP.Trim()].ToString().Trim());

                #region 发送信息
                try
                {
                    Socket TempSocket = ConnectClientDic[ClientIP];
                    byte[] data = System.Text.Encoding.UTF8.GetBytes(cmdstr);

                    TempSocket.Send(data, 0, data.Length, SocketFlags.None);
                }
                catch (Exception ex)
                {

                }
                #endregion
        }
        #endregion


        #region 同步文件
        /// <summary>
        /// 同步文件
        /// </summary>
        /// <param name="LocalPath">本地地址</param>
        /// <param name="RemotePath">同步地址</param>
        /// <returns></returns>
        private bool SyncFile(string ClientIP, string LocalPath)
        {
            if (File.Exists(LocalPath))
            {
                FileInfo fileinfo = new FileInfo(LocalPath);
                FileStream fs = new FileStream(LocalPath, FileMode.Open, FileAccess.Read);

                if (fs.Length > 0)
                {
                    #region 如果有内容则同步文件
                    try
                    {
                        //文件分块传输，分块的大小,单位为字节
                        //现在默认是1M,但是由于自定义协议第一位为协议位，所以数据位少1
                        //SendPacketSize;

                        //分块的数量               
                        int PacketCount = (int)(fileinfo.Length / ((long)SendPacketSize));
                        //最后一个分块的大小           
                        int LastPacketSize = (int)(fileinfo.Length - ((long)(SendPacketSize * PacketCount)));



                        if (ConnectClientDic.ContainsKey(ClientIP.Trim()) && ConnectClientDic[ClientIP.Trim()].Connected)
                        {
                            #region 发送文件名
                            Socket TempSocket = ConnectClientDic[ClientIP.Trim()];
                            //发送命令
                            string CMDString = @"SyncFile," + LocalPath.ToLower().Replace(socketconfig.SyncDir.ToLower(), ClientDic[ClientIP.Trim()].ToString().Trim()) + ",Length=" + fileinfo.Length;
                            byte[] ArrCMD = System.Text.Encoding.UTF8.GetBytes(CMDString);
                            TempSocket.Send(ArrCMD, 0, ArrCMD.Length, SocketFlags.None);

                            AddMsg("Send:" + CMDString);
                            System.Threading.Thread.Sleep(SendInterval * 5);
                            #endregion


                            #region 发送文件
                            //文件按数据包的形式发送，定义数据包的大小      
                            byte[] data = new byte[SendPacketSize];
                            //开始循环发送数据包           
                            for (int i = 0; i < PacketCount; i++)
                            {
                                //从文件流读取数据并填充数据包  
                                fs.Read(data, 0, data.Length);
                                //发送数据包                    
                                TempSocket.Send(data, 0, SendPacketSize, SocketFlags.None);
                                AddMsg("Send:length:" + data.Length);
                                System.Threading.Thread.Sleep(SendInterval);
                            }

                            //发送最后一个数据包   
                            if (LastPacketSize != 0)
                            {
                                byte[] lastdata = new byte[LastPacketSize];
                                fs.Read(lastdata, 0, LastPacketSize);
                                //发送数据包   
                                TempSocket.Send(lastdata, 0, LastPacketSize, SocketFlags.None);
                                AddMsg("Send:length:" + lastdata.Length);
                                AddMsg("发送完毕");
                                System.Threading.Thread.Sleep(SendInterval);
                            }
                            #endregion
                        }
                        
                    }
                    catch (Exception ex)
                    {

                    }
                    #endregion
                }
                fs.Close();
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion


        #region 检测排除目录
        /// <summary>
        /// 检测排除目录
        /// </summary>
        /// <returns></returns>
        private bool CheckExclude(string path)
        {
            bool Result = false;
            if (socketconfig.ExcludeDir.Trim() != "")
            {
                string[] DirArr = socketconfig.ExcludeDir.Split(';');
                foreach (string Dir in DirArr)
                {
                    if (Dir != "" && path.ToLower().Contains(Dir.ToString().ToLower()))
                    {
                        Result = true;
                        break;
                    }
                }
            }
            return Result;
        }
        #endregion


        #region 更新消息
        /// <summary>
        /// 更新消息
        /// </summary>
        /// <param name="Msg"></param>
        private void AddMsg(string Msg)
        {
            Invoke(new MethodInvoker(delegate()
            {
                if (MsgBox.Text.Length > 5000)
                {
                    MsgBox.Text = "";
                }
                MsgBox.AppendText("DateTime:" + DateTime.Now + "," + Msg + "\r");
                MsgBox.ScrollToCaret();
            }));
        }

        /// <summary>
        /// 更新消息
        /// </summary>
        /// <param name="Message"></param>
        private void AddMessage(string Message)
        {
            MsgBox.AppendText("DateTime:" + DateTime.Now + "," + Message + "\r");
        }
        #endregion


        #region 设置发布服务器
        /// <summary>
        /// 设置发布服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgSetServer_Click(object sender, EventArgs e)
        {
            FormServerConfig ServerForm = new FormServerConfig();
            ServerForm.ShowDialog();
        }
        #endregion


        #region 接收服务器管理
        /// <summary>
        /// 接收服务器管理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgClient_Click(object sender, EventArgs e)
        {
            FormClient FormC = new FormClient();
            FormC.ShowDialog();
        }
        #endregion


        #region 启动服务
        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgStart_Click(object sender, EventArgs e)
        {   
           TbServer server= dalserver.GetModel(1);
           if (server == null)
           {
               AddMsg("Server:请先配置发布服务器!");
               return;
           }
           if (!Directory.Exists(server.SyncDir))
           {
               AddMsg("Server:发布服务器同步目录不存在!");
               return;
           }

           ClientBusyDic.Clear();
            
            ///初始化配置信息
            socketconfig = new SocketConfig();
            socketconfig.ServerIP=server.ServerIP;
            socketconfig.ServerPort = server.ServerPort.ToString();
            socketconfig.SyncDir = server.SyncDir;
            socketconfig.SyncFilter = server.SyncFilter;
            socketconfig.ExcludeDir = server.ExcludeDir;

            #region 初始化接收服务器
            ClientDic.Clear();
            DataSet ds= dalclient.GetAllList();
            if(ds!=null&&ds.Tables[0].Rows.Count>0)
            {
                foreach(DataRow dr in ds.Tables[0].Rows)
                {
                    if(!ClientDic.ContainsKey(dr["ClientIP"].ToString().Trim()))
                    {
                        ClientDic.Add(dr["ClientIP"].ToString().Trim(), dr["ClientDir"].ToString().Trim());
                    }
                }
            }
            #endregion

            try
            {     
                AddMsg("Server：" + socketconfig.ServerIP.Trim() + "," + socketconfig.ServerPort.Trim() + "  Start!");
                //创建套接字 
                ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //绑定IP地址和端口到套接字    
                ListenSocket.Bind(socketconfig.GetIPEndPoint());
                //启动监听  
                ListenSocket.Listen(100);//10连接数

                AddMsg("Server:Start Listen!");

                //在一个单独的线程中监听客户连接       
                ListenThread = new Thread(AcceptClient);
                ListenThread.Start();

                //开启发送数据线程
                ThreadSend = new Thread(SendData);
                ThreadSend.Start();

                //开启文件夹监控线程
                WatchDic.Clear();
                WatchConfig wc = new WatchConfig(socketconfig.SyncDir,socketconfig.SyncFilter, (server.ChildDir.Trim()=="True"?true:false));
                Thread threadWatch = new Thread(delegate() { StartWatch(wc); });
                threadWatch.Start();
                if (!WatchThreadDic.ContainsKey(wc.WatchDir))
                {
                    WatchThreadDic.Add(wc.WatchDir, threadWatch);
                }
                else
                {
                    WatchThreadDic[wc.WatchDir] = threadWatch;
                }
                
                //绑定目录树
                BindTree(socketconfig.SyncDir);
                //状态
                ImgStatus.Image = global::FileServer.Properties.Resources.green;
                ImgStart.Enabled = false;
                ImgStop.Enabled = true;
            }
            catch (Exception ex)
            {
                AddMsg("Server:Start Listen Failed!");
                ImgStatus.Image = global::FileServer.Properties.Resources.gray;
            }
        }
        #endregion


        #region 停止服务
        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgStop_Click(object sender, EventArgs e)
        {
            if (ListenThread.IsAlive)
            {
                try
                {
                    //关闭监听线程
                    //ListenThread.Abort();
                    //关闭发送线程
                    ThreadSend.Abort();
                    //关闭客户端连接
                    foreach (var client in ConnectClientDic)
                    {
                        client.Value.Close();
                    }
                    //终止消息接收线程
                    foreach (var client in ReceiveDataDic)
                    {
                        client.Value.Abort();
                    }
                    //关闭socket
                    ListenSocket.Close();
                    ListenSocket.Dispose();
                    //关闭文件夹监控
                    foreach (var wc in WatchDic)
                    {
                        FileSystemWatcher watcher = wc.Value;
                        watcher.Changed -= new FileSystemEventHandler(OnChanged);
                        watcher.Created -= new FileSystemEventHandler(OnCreated);
                        watcher.Deleted -= new FileSystemEventHandler(OnDeleted);
                        watcher.Renamed -= new RenamedEventHandler(OnReNamed);

                        watcher.EnableRaisingEvents = false;
                    }
                    //关闭文件夹监控线程
                    foreach (var wt in WatchThreadDic)
                    {
                        wt.Value.Abort();
                    }
                    AddMsg("Server:stop server!");
                }
                catch (Exception ex)
                {

                }
                ImgStatus.Image = global::FileServer.Properties.Resources.gray;
                ImgStart.Enabled = true;
                ImgStop.Enabled = false;
            }
        }
        #endregion


        #region 手动同步
        /// <summary>
        /// 手动同步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgSync_Click(object sender, EventArgs e)
        {
            if (DirTree.SelectedNode != null)
            {
                string Path = DirTree.SelectedNode.Name.Trim();
                //不能同步根目录
                if (socketconfig != null && Path != socketconfig.SyncDir)
                {
                    #region 同步该路径
                    //同步文件夹
                    if (FileHelp.CheckFileDir(Path) == 0)
                    {
                        foreach (var kv in ClientDic)
                        {
                            if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                            {
                                AddCMD(kv.Key.Trim()+";NewDir," + Path);
                            }
                        }

                        #region 同步子目录同步文件
                        //如果有子目录表示移动产生的新建
                        //则创建子目录同步所有文件
                        List<string> list = new List<string>();
                        list = FileHelp.GetAllFolder(Path, list);
                        if (list != null && list.Count > 0)
                        {
                            foreach (string path in list)
                            {
                                foreach (var kv in ClientDic)
                                {
                                    if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                    {
                                        //同步文件夹
                                        AddCMD(kv.Key.Trim()+";NewDir," + path.ToString());
                                    }
                                }

                                //同步文件
                                List<string> listfile = FileHelp.GetAllFile(path.ToString());
                                if (listfile != null && listfile.Count > 0)
                                {
                                    foreach (string filepath in listfile)
                                    {
                                        foreach (var kv in ClientDic)
                                        {
                                            if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                            {
                                                AddCMD(kv.Key.Trim() + ";SyncFile," + filepath);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //同步一级目录文件
                        list = new List<string>();
                        list = FileHelp.GetAllFile(Path);
                        if (list != null && list.Count > 0)
                        {
                            foreach (string filepath in list)
                            {
                                foreach (var kv in ClientDic)
                                {
                                    if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                                    {
                                        AddCMD(kv.Key.Trim()+";SyncFile," + filepath);
                                    }
                                }
                            }
                        }
                        #endregion
                    }

                    //同步文件
                    if (FileHelp.CheckFileDir(Path) == 1)
                    {
                        foreach (var kv in ClientDic)
                        {
                            if (ConnectClientDic.ContainsKey(kv.Key.Trim()))
                            {
                                AddCMD(kv.Key.Trim()+";SyncFile," + Path);
                            }
                        }
                    }
                    #endregion
                }
            }
            else
            {
                MessageBox.Show("请选择需要手动同步的文件","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
        }
        #endregion


        #region 刷新目录
        /// <summary>
        /// 刷新目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgRefrash_Click(object sender, EventArgs e)
        {
            if (socketconfig != null && socketconfig.SyncDir.Trim() != "")
            {
                //绑定目录树
                BindTree(socketconfig.SyncDir);
            }
        }
        #endregion


        #region 清空日志
        /// <summary>
        /// 清空日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImgClear_Click(object sender, EventArgs e)
        {
            MsgBox.Clear();
        }
        #endregion


        #region 绑定树节点
        /// <summary>
        /// 绑定树节点
        /// </summary>
        /// <param name="Path"></param>
        private void BindTree(string Path)
        {
            DirTree.Nodes.Clear();
            if (!Directory.Exists(Path)) return;
            DirTree.ImageList = ImgList;
            DirectoryInfo dir = new DirectoryInfo(Path);
            TreeNode rootNode = new TreeNode();
            rootNode.Text = dir.Name;
            rootNode.Name = Path;
            rootNode.Expand();
            rootNode.ImageIndex = 0;
            rootNode.SelectedImageIndex = 0;
            DirTree.Nodes.Add(rootNode);
            TraversingCatalog(rootNode,Path);
        }
        #endregion


        #region 递归调用加载目录
        /// <summary>
        /// 递归调用加载目录
        /// </summary>
        /// <param name="node"></param>
        /// <param name="Path"></param>
        private bool TraversingCatalog(TreeNode node, string Path) 
        {
            if (Directory.Exists(Path) == false) { return false; }
            DirectoryInfo dirInfo = new DirectoryInfo(Path);
            int allNum = dirInfo.GetDirectories().Length + dirInfo.GetFiles("*.*").Length;
            if (allNum == 0)
            {
                return false;
            }

            //循环文件
            foreach (FileInfo file in dirInfo.GetFiles("*.*"))
            {
                TreeNode fileNode = new TreeNode(); 
                fileNode.Text = file.Name; //得到文件名                  
                fileNode.Name = file.FullName; //得到文件的详细本地路径                 
                fileNode.ToolTipText = file.Name; //得到文件名                 
                fileNode.Expand(); //折叠节点                  
                fileNode.ImageIndex = 1; //节点图片                 
                fileNode.SelectedImageIndex = 1;
                node.Nodes.Add(fileNode); //添加新节点 
            }

            //循环文件夹
            foreach (DirectoryInfo folder in dirInfo.GetDirectories())
            {
                TreeNode folderNode = new TreeNode(); 
                folderNode.Text = folder.Name; //得到文件夹名                  
                folderNode.Name = folder.FullName; //得到文件夹的详细本地路径                 
                folderNode.ToolTipText = folder.Name; //得到文件夹名                 
                folderNode.Expand(); //折叠节点                  
                folderNode.ImageIndex = 0; //节点图片     
                folderNode.SelectedImageIndex = 0;
                node.Nodes.Add(folderNode); //添加新节点  
                if (folder.GetDirectories().Length + folder.GetFiles("*.*").Length > 0)
                {
                    TraversingCatalog(folderNode, Path + "/" + folder.Name); //递归遍
                }
            }
            return true;
        }
        #endregion

    }
    
}
